/******************************************************************************
 * 
 *Taylor Chan's works,just for practice!
 * 
 *****************************************************************************/

package com.cq.thinkinjava.concurrent.cancelthread;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * 使用interrupt的方式，关键在于获取线程上下文
 * 
 * @author Taylor Chan
 * @since 1.0
 * @version 2012-7-25 Taylor Chan Creat
 */
public class InterruptThread {
    
    private static ExecutorService exec = Executors.newCachedThreadPool();
    
    static void test(Runnable r) {
        Future<?> f = exec.submit(r);// 线程的上下文对象
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO 自动生成异常捕获块存根注释，块实现时请删除此注释
            e.printStackTrace();
        }
        System.out.println("interrupting " + r.getClass().getName());
        f.cancel(true);// 设置中止
        System.out.println("interrupt has sent to " + r.getClass().getName());
    }
    
    public static void main(String[] args) {
        // 可以中断sleep中的线程
        test(new SleepBlocked());
        // 对io的中断操作不能奏效
        test(new IOBlocked(System.in));
        // 不能中断试图获取syc锁的线程
        test(new SynchronizedBlock());
    }
}

class SleepBlocked implements Runnable {
    
    /**
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            TimeUnit.MILLISECONDS.sleep(200L);
        } catch (InterruptedException e) {
            // TODO 自动生成异常捕获块存根注释，块实现时请删除此注释
            e.printStackTrace();
            System.out.println("Interrupted Exception! ");
        }
        System.out.println("Exiting SleepBlocked.run()");
    }
}

class IOBlocked implements Runnable {
    
    private final InputStream in;
    
    /**
     * 
     */
    public IOBlocked(InputStream is) {
        this.in = is;
    }
    
    /**
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            System.out.println("waiting for input: ");
            in.read();
        } catch (IOException e) {
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("Interruptted from blocked I/O");
            } else
                throw new RuntimeException(e);
        }
        System.out.println("Exiting IOBlocked.run()");
    }
}

class SynchronizedBlock implements Runnable {
    
    public synchronized void f() {
        while (true) {
            System.out.println("now in: " + Thread.currentThread().getName() + " f() ");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO 自动生成异常捕获块存根注释，块实现时请删除此注释
                e.printStackTrace();
            }
        }
        
    }
    
    /**
     * 
     */
    public SynchronizedBlock() {
        new Thread("thread000") {// thread000通过调用f()获取到对象锁，由于f()是死循环，所以thread000永远获取锁不放
        
            @Override
            public void run() {
                f();
            }
        }.start();
    }
    
    /**
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        System.out.println("try to call f()");// thread000不放开锁，以至于本线程阻塞等待获取synchronized锁
        f();
        System.out.println("Exiting SynchronizedBlock.run()");
    }
    
}
